from rest_framework import serializers

from .models import SequenceAnnotation,RelationAnnotation,AttributeAnnotation
from .models import Label, Project, Document, Setting, RecommendationHistory, RelationLabel, AttributeLabel,\
    RecommendationRule, PreSettings, TrainedModel


class LabelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Label
        fields = ('id', 'text', 'shortcut', 'background_color', 'text_color')


class RelationLabelSerializer(serializers.ModelSerializer):
    class Meta:
        model= RelationLabel
        fields = ('id', 'relation_name','head_label','tail_label')


class AttributeLabelSerializer(serializers.ModelSerializer):
    class Meta:
        model= AttributeLabel
        fields = ('id', 'attribute_name','label')


class PreSettingsSerializer(serializers.ModelSerializer):
    class Meta:
        model = PreSettings
        fields = ['preSetPercent', 'preSetAcc']


class SettingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Setting
        fields = ('id','model_name','model_config','optimizer_config','rule', 'onlinelearning', 'history',
                  'active', 'acquire')

    def update(self, instance, validated_data):
        instance.model_name=validated_data.get('model_name',instance.model_name)
        instance.model_config=validated_data.get('model_config',instance.model_config)
        instance.optimizer_config=validated_data.get('optimizer_config',instance.optimizer_config)
        instance.rule = validated_data.get('rule', instance.rule)
        instance.onlinelearning = validated_data.get('onlinelearning', instance.onlinelearning)
        instance.history = validated_data.get('history', instance.history)
        instance.active = validated_data.get('active', instance.active)
        instance.acquire = validated_data.get('acquire', instance.acquire)
        instance.save()
        return instance


class DocumentSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        many = kwargs.pop('many', True)
        super(DocumentSerializer, self).__init__(many=many, *args, **kwargs)

    class Meta:
        model = Document
        fields = ('id', 'text', 'annotated','related','submitted','annotating')

    def update(self, instance, validated_data):
        instance.annotated = validated_data.get('annotated', instance.annotated)
        instance.related=validated_data.get('related',instance.related)
        instance.submitted=validated_data.get('submitted',instance.submitted)
        instance.annotating=validated_data.get('annotating',instance.annotating)
        instance.save()
        return instance

    def create(self, validated_data):
        docs = [Document(**item) for item in validated_data]
        return Document.objects.bulk_create(docs)


class ProjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = ('id', 'name', 'description', 'guideline', 'users', 'image', 'updated_at')


class ProjectFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        view = self.context.get('view', None)
        request = self.context.get('request', None)
        queryset = super(ProjectFilteredPrimaryKeyRelatedField, self).get_queryset()
        if not request or not queryset or not view:
            return None
        return queryset.filter(project=view.kwargs['project_id'])


class LabelFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        view = self.context.get('view', None)
        request = self.context.get('request', None)
        queryset = super(LabelFilteredPrimaryKeyRelatedField, self).get_queryset()
        if not request or not queryset or not view:
            return None
        sequenceAnnotation=SequenceAnnotation.objects.all().filter(pk=request.data['from_label'])[0]
        label=sequenceAnnotation.label.id
        return queryset.filter(label=label)


class LabelsFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        view = self.context.get('view', None)
        request = self.context.get('request', None)
        queryset = super(LabelsFilteredPrimaryKeyRelatedField, self).get_queryset()
        if not request or not queryset or not view:
            return None
        from_sequenceAnnotation = SequenceAnnotation.objects.all().filter(pk=request.data['from_label'])[0]
        head_label = from_sequenceAnnotation.label.id
        to_sequenceAnnotation = SequenceAnnotation.objects.all().filter(pk=request.data['to_label'])[0]
        tail_label=to_sequenceAnnotation.label.id
        return queryset.filter(head_label=head_label,tail_label=tail_label)


class SequenceAnnotationSerializer(serializers.ModelSerializer):
    label = ProjectFilteredPrimaryKeyRelatedField(allow_null=True,queryset=Label.objects.all())

    class Meta:
        model = SequenceAnnotation
        fields = ('id', 'prob', 'label', 'start_offset', 'end_offset','text')

    def create(self, validated_data):
        annotation = SequenceAnnotation.objects.create(**validated_data)
        return annotation

    def validate(self,attrs):
        label=attrs.get('label')
        print(label,type(label))
        return attrs


class RelationAnnotationSerializer(serializers.ModelSerializer):
    relation_label=LabelsFilteredPrimaryKeyRelatedField(queryset=RelationLabel.objects.all())
    class Meta:
        model=RelationAnnotation
        fields=('id','relation_label','from_label','to_label','is_recommend')

    def create(self,validated_data):
        relation_annotation=RelationAnnotation.objects.create(**validated_data)
        return relation_annotation

    def update(self, instance, validated_data):
        instance.is_recommend = validated_data.get('is_recommend', instance.is_recommend)
        instance.save()
        return instance


class AttributeAnnotationSerializer(serializers.ModelSerializer):
    attribute_label = LabelFilteredPrimaryKeyRelatedField(queryset=AttributeLabel.objects.all())
    class Meta:
        model=AttributeAnnotation
        fields=('id','attribute_label','from_label','to_label','is_recommend')

    def create(self,validated_data):
        attribute_annotation=AttributeAnnotation.objects.create(**validated_data)
        return attribute_annotation

    def update(self, instance, validated_data):
        instance.is_recommend = validated_data.get('is_recommend', instance.is_recommend)
        instance.save()
        return instance

    def validate(self,attrs):
        attribute_label=attrs.get('attribute_label')
        print(attribute_label,type(attribute_label))
        return attrs


class SequenceDocumentSerializer(serializers.ModelSerializer):
    annotations = serializers.SerializerMethodField()

    def get_annotations(self, instance):
        request = self.context.get('request')
        if request:
            annotations = instance.seq_annotations.filter(user=request.user)
            serializer = SequenceAnnotationSerializer(annotations, many=True)
            return serializer.data

    class Meta:
        model = Document
        fields = ('id', 'text', 'annotations', 'annotated','submitted','annotating')


class RecommendationHistorySerializer(serializers.ModelSerializer):
    class Meta:
        model = RecommendationHistory
        fields = ('id', 'word', 'label')


class RecommendationRuleSerializer(serializers.ModelSerializer):
    class Meta:
        model = RecommendationRule
        fields = ('id', 'rule', 'label')


class TrainedModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TrainedModel
        fields = "__all__"

    def validate(self, attrs):
        """
        执行自定义的验证逻辑，确保在 dataset为空的情况下，project是提供的。
        """
        dataset_name = attrs.get('dataset')
        project = attrs.get('project')
        # 当 dataset_name 为空时，确保 project 存在
        if not dataset_name and not project:
            raise serializers.ValidationError({
                'project': '未指定 dataset 时，project 是必需的。'
            })

        return attrs
